<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <meta name="description" content="OrgSync">
    <title>重置密码 - OrgSync</title>
    <link rel="icon" href="/favicon.ico">
    <link rel="apple-touch-icon" href="/logo192.png">
    <link rel="manifest" href="/manifest.json">
    <link rel="stylesheet" href="/libs/bootstrap@5.3.3/css/bootstrap.min.css">
    <link rel="stylesheet" href="/css/verify.css">
    <style>
        html, body {
            height: 100%;
        }

        body {
            background-color: #ffffff;
            position: relative;
        }

        .reset-box {
            max-width: 360px !important;
            min-width: 280px !important;
            user-select: none;
        }

        .reset-header {
            padding: 40px 0 32px;
            text-align: center;
        }

        .reset-header .logo {
            margin-bottom: 24px;
            width: 96px;
            height: auto;
        }

        .reset-body form fieldset {
            position: relative;
        }

        .form-floating > .form-control-plaintext~label::after,
        .form-floating > .form-control:focus~label::after,
        .form-floating > .form-control:not(:placeholder-shown)~label::after,
        .form-floating > .form-select~label::after {
            display: none;
        }

        .btn-link {
            text-decoration: none;
        }

        .verification-codes .form-control {
            font-weight: 600;
            text-align: center;
            width: 48px;
        }

        .step3 .form-control {
            background-size: 20px 20px !important;
            padding-left: 32px;
        }

        .step3 .form-control.username {
            background: url("") no-repeat 8px center / cover;
        }

        .step3 .form-control.password {
            background: url("") no-repeat 8px center / cover;
        }

        .loading-box {
            background-color: rgba(0, 0, 0, 0.65);
            border-radius: 8px;
            box-shadow: rgba(33, 37, 41, 0.35) 0px 8px 16px 0px;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 64px;
            height: 64px;
        }

        .reset-box.step1 .reset-header p.step1 {
            display: block;
        }
        .reset-box.step1 .reset-header p.step2 {
            display: none;
        }
        .reset-box.step1 .reset-header p.step3 {
            display: none;
        }
        .reset-box.step1 .reset-body div.step1 {
            display: block;
        }
        .reset-box.step1 .reset-body div.step2 {
            display: none;
        }
        .reset-box.step1 .reset-body div.step3 {
            display: none;
        }

        .reset-box.step2 .reset-header p.step1 {
            display: none;
        }
        .reset-box.step2 .reset-header p.step2 {
            display: block;
        }
        .reset-box.step2 .reset-header p.step3 {
            display: none;
        }
        .reset-box.step2 .reset-body div.step1 {
            display: none;
        }
        .reset-box.step2 .reset-body div.step2 {
            display: block;
        }
        .reset-box.step2 .reset-body div.step3 {
            display: none;
        }

        .reset-box.step3 .reset-header p.step1 {
            display: none;
        }
        .reset-box.step3 .reset-header p.step2 {
            display: none;
        }
        .reset-box.step3 .reset-header p.step3 {
            display: block;
        }
        .reset-box.step3 .reset-body div.step1 {
            display: none;
        }
        .reset-box.step3 .reset-body div.step2 {
            display: none;
        }
        .reset-box.step3 .reset-body div.step3 {
            display: block;
        }
    </style>
</head>
<body>
    <div class="container reset-box step1">
        <div class="reset-header">
            <img src="/images/reset_password.png" alt="logo" class="logo">
            <h3>重置密码</h3>
            <p class="text-muted step1">请输入用户名 / 手机号码重置您的密码</p>
            <p class="text-muted step2">
                一条包含验证码的信息已发送至你的手机
                <strong class="d-block"></strong>
            </p>
            <p class="text-muted step3">请输入新密码以重置密码</p>
        </div>
        <div class="reset-body">
            <form>
                <fieldset>
                    <div class="alert text-center mb-4 d-none"></div>
                    <div class="step1">
                        <div class="form-floating mb-4">
                            <input id="username" name="username" type="text" maxlength="32"
                                   placeholder="用户名 / 手机号码" class="form-control">
                            <input name="captchaVerification" type="hidden">
                            <label for="username">用户名 / 手机号码</label>
                        </div>
                        <button type="button" class="btn btn-lg btn-primary w-100">重置密码</button>
                    </div>
                    <div class="step2">
                        <div class="verification-codes d-flex justify-content-center">
                            <input name="verificationCode" type="text" maxlength="1"
                                   pattern="[0-9]*" inputmode="numeric" autocomplete="off"
                                   class="form-control form-control-lg mx-2" data-index="0">
                            <input name="verificationCode" type="text" maxlength="1"
                                   pattern="[0-9]*" inputmode="numeric" autocomplete="off"
                                   class="form-control form-control-lg mx-2" data-index="1">
                            <input name="verificationCode" type="text" maxlength="1"
                                   pattern="[0-9]*" inputmode="numeric" autocomplete="off"
                                   class="form-control form-control-lg mx-2" data-index="2">
                            <input name="verificationCode" type="text" maxlength="1"
                                   pattern="[0-9]*" inputmode="numeric" autocomplete="off"
                                   class="form-control form-control-lg mx-2" data-index="3">
                        </div>
                        <p class="text-muted text-center mt-4 mb-1">请输入验证码以继续</p>
                        <button type="button" class="btn btn-link w-100 d-none">没收到验证码？点此重发</button>
                        <p class="countdown-text text-muted text-center">
                            <span></span>
                            秒后可重发
                        </p>
                    </div>
                    <div class="step3">
                        <input name="username" type="text" readonly class="form-control username mb-3">
                        <input name="password" type="password" placeholder="新密码"
                               minlength="6" maxlength="16" autocomplete="off"
                               class="form-control password mb-3">
                        <input name="confirmPassword" type="password" placeholder="再次输入新密码"
                               minlength="6" maxlength="16" autocomplete="off"
                               class="form-control password mb-4">
                        <button type="button" class="btn btn-lg btn-primary w-100">重置密码</button>
                    </div>
                    <p class="text-secondary text-center mt-5">© OrgSync 2024</p>
                    <div class="loading-box d-flex align-items-center justify-content-center d-none">
                        <div class="spinner-border text-light"></div>
                    </div>
                </fieldset>
            </form>
        </div>
    </div>

    <div id="verify-modal"></div>

    <script src="/libs/bootstrap@5.3.3/js/bootstrap.bundle.min.js"></script>
    <script src="/libs/axios@1.7.2/axios.min.js"></script>
    <script src="/libs/crypto-js@4.0.0/crypto-js.js"></script>
    <script src="/js/verify.js"></script>

    <script>
        var modalVerify = null;
        var resetBox = document.querySelector('.reset-box');
        var step1Button = document.querySelector('.step1 .btn-primary');
        var step2Button = document.querySelector('.step2 .btn-link');
        var step3Button = document.querySelector('.step3 .btn-primary');
        var codeInputs = document.querySelectorAll('.step2 input[name="verificationCode"]');
        var countdownText = document.querySelector('.step2 .countdown-text');
        var loadingBox = document.querySelector('.loading-box');

        for (var i = 0; i < codeInputs.length; i++) {
            codeInputs[i].addEventListener('keydown', function (e) {
                var index = parseInt(e.target.dataset.index);
                e.preventDefault();
                e.stopPropagation();
                if ('0123456789'.indexOf(e.key) >= 0) {
                    e.target.value = e.key;
                    if (index < 3) {
                        codeInputs[index + 1].focus();
                    }
                } else if (e.key === 'Backspace') {
                    if (e.target.value) {
                        e.target.value = '';
                    } else {
                        if (index > 0) {
                            codeInputs[index - 1].focus();
                        }
                    }
                } else if (e.key === 'ArrowLeft') {
                    if (index > 0) {
                        codeInputs[index - 1].focus();
                    }
                } else if (e.key === 'ArrowRight' || e.key === 'Enter') {
                    if (index < 3) {
                        codeInputs[index + 1].focus();
                    }
                }
                var code = getVerificationCode();
                if (code.length === 4) {
                    checkVerificationCode(code);
                }
            });
        }

        step1Button.addEventListener('click', function () {
            var usernameInput = document.querySelector('.step1 input[name="username"]');
            var username = (usernameInput.value || '').trim();
            usernameInput.value = username;
            if (!username) {
                showAlert('请输入用户名或手机号码', 'warning');
                return;
            }
            showModalVerify();
        });

        step2Button.addEventListener('click', function () {
            showModalVerify();
        });

        step3Button.addEventListener('click', function () {
            var username = document.querySelector('.step3 input[name="username"]').value;
            var password = document.querySelector('.step3 input[name="password"]').value;
            var confirmPassword = document.querySelector('.step3 input[name="confirmPassword"]').value;
            var verificationCode = getVerificationCode();
            if (!password) {
                showAlert('密码不能为空', 'warning');
                return;
            }
            if (!confirmPassword) {
                showAlert('确认密码不能为空', 'warning');
                return;
            }
            loadingBox.classList.remove('d-none');
            showAlert('');
            axios.post('/api/user/resetPassword', {
                username: username,
                password: password,
                confirmPassword: confirmPassword,
                verificationCode: verificationCode
            }).then(function (response) {
                var flag = response.data && response.data.data && response.data.data === 'admin';
                loadingBox.classList.add('d-none');
                showAlert('密码重置成功', 'success');
                var timeoutId = setTimeout(function () {
                    var newUser = {
                        username: username,
                        expiry: new Date().getTime() + 15000
                    };
                    localStorage.setItem('NewUser', JSON.stringify(newUser));
                    clearTimeout(timeoutId);
                    location.href = flag ? '/' : '/sign_in';
                }, 3000);
            }).catch(function (error) {
                var message = '密码重置失败';
                var type = 'danger';
                if (error && error.response && error.response.data && error.response.data.message) {
                    message = error.response.data.message;
                    type = error.response.data.code === 500 ? 'danger' : 'warning';
                }
                loadingBox.classList.add('d-none');
                showAlert(message, type);
            });
        });

        function getVerificationCode() {
            var verificationCode = '';
            for (var i = 0; i < codeInputs.length; i++) {
                verificationCode += codeInputs[i].value;
            }
            return verificationCode;
        }

        function checkVerificationCode(code) {
            var username = document.querySelector('.step1 input[name="username"]').value;
            var captchaVerification = document.querySelector('input[name="captchaVerification"]').value;
            var data = {
                username: username,
                verificationCode: code,
                usage: 1,
                captchaVerification: captchaVerification
            };
            loadingBox.classList.remove('d-none');
            showAlert('');
            axios.post('/api/checkVerificationCode', data).then(function (response) {
                loadingBox.classList.add('d-none');
                showStep(3);
            }).catch(function (error) {
                var message = '验证码不正确';
                var type = 'warning';
                if (error && error.response && error.response.data && error.response.data.message) {
                    message = error.response.data.message;
                    type = error.response.data.code === 500 ? 'danger' : 'warning';
                }
                loadingBox.classList.add('d-none');
                showAlert(message, type);
            });
        }

        function showStep(index) {
            resetBox.classList.remove('step1');
            resetBox.classList.remove('step2');
            resetBox.classList.remove('step3');
            resetBox.classList.add('step' + index);
        }

        function showModalVerify() {
            showAlert('');
            if (!modalVerify) {
                modalVerify = new ModalVerify('#verify-modal', {
                    success: function (data) {
                        var username = document.querySelector('input[name="username"]').value;
                        document.querySelector('input[name="captchaVerification"]').value = data.captchaVerification;
                        loadingBox.classList.remove('d-none');
                        showAlert('');
                        axios.post('/api/sendVerificationCode', {
                            username: username,
                            usage: 1,
                            captchaVerification: data.captchaVerification
                        }).then(function (response) {
                            loadingBox.classList.add('d-none');
                            showStep(2);
                            document.querySelector('.step3 input[name="username"]').value = username;
                            document.querySelector('.text-muted.step2 strong').innerText = response.data.data;
                            step2Button.classList.add('d-none');
                            countdownText.classList.remove('d-none');
                            countdownText.countdown = 61;
                            for (var i = 0; i < codeInputs.length; i++) {
                                codeInputs[i].value = '';
                            }
                            codeInputs[0].focus();
                            var intervalId = setInterval(function () {
                                countdownText.countdown = countdownText.countdown - 1;
                                if (countdownText.countdown <= 0) {
                                    clearInterval(intervalId);
                                    step2Button.classList.remove('d-none');
                                    countdownText.classList.add('d-none');
                                } else {
                                    countdownText.querySelector('span').innerText = countdownText.countdown;
                                }
                            }, 1000);
                        }).catch(function (error) {
                            var message = '验证码发送失败';
                            var type = 'danger';
                            if (error && error.response && error.response.data && error.response.data.message) {
                                message = error.response.data.message;
                                type = error.response.data.code === 500 ? 'danger' : 'warning';
                            }
                            loadingBox.classList.add('d-none');
                            showAlert(message, type);
                        });
                    }
                }).init();
            }
            modalVerify.show();
        }

        function showAlert(message, type) {
            var alert = document.querySelector('.alert');
            for (var i = alert.classList.length - 1; i >= 0; i--) {
                if (alert.classList[i].indexOf('alert-') === 0) {
                    alert.classList.remove(alert.classList[i]);
                }
            }
            if (type) {
                alert.classList.add('alert-' + type);
            }
            alert.innerText = message;
            if (message) {
                alert.classList.remove('d-none');
            } else {
                alert.classList.add('d-none');
            }
        }
    </script>
</body>
</html>
